package common;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.StringTokenizer;


public class Utils{
	public static void printIp( long ip ){
		System.out.print( ipToString( ip ) );
	}
	
	public static String ipToString( long ip ){
		long classA = ip / 256 / 256 / 256;
		long classB = ip / 256 / 256 % 256;
		long classC = ip / 256 % 256;
		long classD = ip % 256;
		
		return new String( classA + "." + classB + "." + classC + "." + classD );
	}
	
	public static long stringToIp( String s ){
		long classA, classB, classC, classD;
		StringTokenizer st = new StringTokenizer( s, "." ); 
		
		if( st.countTokens() != 4 )
			return -1;
		
		try{
			classA = Long.parseLong( st.nextToken() );
			classB = Long.parseLong( st.nextToken() );
			classC = Long.parseLong( st.nextToken() );
			classD = Long.parseLong( st.nextToken() );
		}catch( NumberFormatException e ){
			e.printStackTrace();
			return -1;
		}
		
		return ( ( classA * 256 + classB ) * 256 + classC ) * 256 + classD;
	}
	
	public static boolean isNumber( String s ){
		try{
			Double.parseDouble( s );
		}catch( NumberFormatException e ){
			return false;
		}
		return true;
	}

	
	// Sntp receiver - taken from http://support.ntp.org/bin/view/Support/JavaSntpClient (GPL)
	public static long get_ntp_time() throws IOException{
		String serverName = "time.falk.us";
		// Send request
		DatagramSocket socket = new DatagramSocket();
		InetAddress address = InetAddress.getByName(serverName);
		byte[] buf = new NtpMessage().toByteArray();
		DatagramPacket packet =
			new DatagramPacket(buf, buf.length, address, 123);
		
		// Set the transmit timestamp *just* before sending the packet
		// ToDo: Does this actually improve performance or not?
		NtpMessage.encodeTimestamp(packet.getData(), 40,
			(System.currentTimeMillis()/1000.0) + 2208988800.0);
		
		socket.send(packet);
		
		// Get response
		//System.out.println("NTP request sent, waiting for response...\n");
		packet = new DatagramPacket(buf, buf.length);
		socket.receive(packet);
		
		// Immediately record the incoming timestamp
//		double destinationTimestamp = (System.currentTimeMillis()/1000.0) + 2208988800.0;
		
		// Process response
		NtpMessage msg = new NtpMessage(packet.getData());
		
//		// Corrected, according to RFC2030 errata
//		double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
//			(msg.transmitTimestamp-msg.receiveTimestamp);
//		double localClockOffset = ((msg.receiveTimestamp - msg.originateTimestamp) +
//								(msg.transmitTimestamp - destinationTimestamp)) / 2;
//		
//		// Display response
//		//System.out.println("NTP server: " + serverName);
//		//System.out.println(msg.toString());
//		System.out.println("Dest. timestamp:     " + NtpMessage.timestampToString(destinationTimestamp));
//		System.out.println("Round-trip delay: " + new DecimalFormat("0.00").format(roundTripDelay*1000) + " ms");
//		System.out.println("Local clock offset: " + new DecimalFormat("0.00").format(localClockOffset*1000) + " ms");
//		
		socket.close();
		
		return ( long )msg.referenceTimestamp;
	}
	
	// dump wrapper
	public static void print_log( String log ){
		print_log( log, Def.STDOUT );
	}
	
	public static void print_log( String log, byte target ){
		if( !Conf.VERBOSE )
			return;
		
		if( target == Def.STDOUT ){
			//System.out.print( "[MSG|" + pid + ":" + Utils.ipToString( ip ) + "(" + localtime_s + ")] " );
			System.out.println( log );
		}else if( target == Def.STDERR ){
			//System.err.print( "[ERR|" + pid + ":" + Utils.ipToString( ip ) + "(" + localtime_s + ")] " );
			System.err.println( log );
		}
	}
}//end-of-class
